package com.woniu.coupon.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.enums.ExceptionCode;
import com.ruoyi.common.exception.CustomException;
import com.woniu.coupon.feign.UserFeign;
import com.woniu.user.domain.CustomerCoupon;


import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.woniu.coupon.feign.CustomerFeign;
import com.woniu.coupon.mapper.CouponApartRefMapper;
import com.woniu.coupon.vo.CouponVoForBook;
import com.woniu.user.domain.CustomerCoupon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.woniu.coupon.mapper.CouponMapper;
import com.woniu.coupon.domain.Coupon;
import com.woniu.coupon.service.ICouponService;
import org.springframework.util.CollectionUtils;
import org.springframework.transaction.annotation.Transactional;

/**
 * 优惠券Service业务层处理
 *
 * @author yy
 * @date 2023-04-03
 */
@Service
public class CouponServiceImpl implements ICouponService {
    @Autowired
    private CouponMapper couponMapper;

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private CouponApartRefMapper couponApartRefMapper;

    @Autowired
    private CustomerFeign customerFeign;

    /**
     * 查询优惠券
     *
     * @param id 优惠券主键
     * @return 优惠券
     */
    @Override
    @Transactional
    public Coupon selectCouponById(Long id) {
        return couponMapper.selectCouponById(id);
    }

    /**
     * 查询优惠券列表
     *
     * @param coupon 优惠券
     * @return 优惠券
     */
    @Override
    public List<Coupon> selectCouponList(Coupon coupon) {
        return couponMapper.selectCouponList(coupon);
    }

    /**
     * 新增优惠券
     *
     * @param coupon 优惠券
     * @return 结果
     */
    @Override
    public int insertCoupon(Coupon coupon) {
        return couponMapper.insertCoupon(coupon);
    }

    /**
     * 修改优惠券
     *
     * @param coupon 优惠券
     * @return 结果
     */
    @Override
    public int updateCoupon(Coupon coupon) {
        return couponMapper.updateCoupon(coupon);
    }

    /**
     * 批量删除优惠券
     *
     * @param ids 需要删除的优惠券主键
     * @return 结果
     */
    @Override
    public int deleteCouponByIds(Long[] ids) {
        return couponMapper.deleteCouponByIds(ids);
    }

    /**
     * 删除优惠券信息
     *
     * @param id 优惠券主键
     * @return 结果
     */
    @Override
    public int deleteCouponById(Long id) {
        return couponMapper.deleteCouponById(id);
    }

    @Override
    public void getNewCoupon(Long id, Long CustomerId) {
        //判断该用户是否领过优惠券
        CustomerCoupon customer = userFeign.selectOneByUserIdAndCustomerId(CustomerId, id);
        if (!Objects.isNull(customer)) {
            throw new CustomException(ExceptionCode.HAVE_CUSTOMER_COUPON);
        }

        Coupon coupon = couponMapper.selectCouponById(id);
        //判断是否在优惠券的领取日期区间
        if (!coupon.getIssueStartDate().before(new Date()) || !coupon.getIssueEndDate().after(new Date())) {
            throw new CustomException(ExceptionCode.OUT_TIME_COUPON);
        }
        //判断还有没有优惠券
        if (coupon.getIssuedCount() == 0) {
            throw new CustomException(ExceptionCode.HAVE_NO_COUPON);
        }

        //加锁,防止超量领取
        RLock lock = redissonClient.getLock("redis_coupon_index_lock");
        try {
            lock.lock();

            //减少优惠券数量
            coupon.setIssuedCount(coupon.getIssuedCount() - 1);
            coupon.setGotCount(coupon.getGotCount() + 1);
            couponMapper.updateCoupon(coupon);
            //给用户添加优惠券
            CustomerCoupon customerCoupon = new CustomerCoupon();
            customerCoupon.setCustomerId(CustomerId);
            customerCoupon.setCouponId(id);
            customerCoupon.setCouponStatus(0l);
            customerCoupon.setUsed(0l);
            customerCoupon.setValidStartDate(new Date());
            Date date = new Date();
            long l = date.getTime() + 1000 * 60 * 60 * 24 * coupon.getValidDuration();
            date.setTime(l);
            customerCoupon.setValidEndDate(date);
            Long add = userFeign.add(customerCoupon);
            //发送死信,到过期时间更改用户优惠券的状态
            rabbitTemplate.convertAndSend(UserConstants.DELAY_CUSTOMER_COUPON_EXCHANGE,
                    UserConstants.DELAY_CUSTOMER_COUPON_KEY, add);
        } finally {
            lock.unlock();
        }
    }

    @Override
    public List<Coupon> queryCouponByApartmentIdAndCustomerId(Integer apartmentId, int customerId) {
        //查公寓相关的优惠券
        List<Integer> apartCouponIdList = couponApartRefMapper.selectCouponByApartId(apartmentId);

        //查用户相关的优惠券
        List<Integer> customerCouponIdList = customerFeign.getCustomerCoupon(customerId);


        List<Integer> couponIdList = Stream.concat(apartCouponIdList.stream(), customerCouponIdList.stream()).collect(Collectors.toList());

        List<Coupon> couponList = new ArrayList<>();

        if (couponIdList.size() > 0) {
            couponList = couponMapper.selectCouponInId(couponIdList);
        }

        return couponList;
    }
}
